<?php
/**
 * UploadService.php class file.
 * @author wudg <544038230@qq.com>
 * @date 2020/11/25- 1:55 下午
 */

namespace common\services;


use AliCloud\OSS\Core\OssException;
use AliCloud\OSS\OssClient;
use common\exception\ServicesException;
use common\helpers\ImagesHelper;
use common\models\com\ComImages;
use yii\base\UserException;
use yii\helpers\FileHelper;
use yii\web\UploadedFile;
use Yii;

class UploadService
{
    /**
     * 二级制流形式本地文件上传
     * @param $fileName
     * @return array
     * @throws \yii\base\Exception
     */
    public function localSaveFile($fileName)
    {
        try {

            if (empty($fileName)) throw new ServicesException('not find fileName');

            $allowType = Yii::$app->params['allowUpload'];
            $images = UploadedFile::getInstanceByName($fileName);
            $path = Yii::$app->basePath . Yii::$app->params['upload_path'];
            $save = '/' . date('Y/m/d') . "/";
            $save_path = $path . $save;
            $name = substr($images->name, 0, strrpos($images->name, '.'));

            if (!is_dir($save_path)) {
                FileHelper::createDirectory($save_path);
            }
            $ext = $images->getExtension();
            $size = $images->size;

            //文件尺寸限制20M
            if ($size > 20 * 1024 * 1024) {
                throw new ServicesException("上传文件尺寸超出限制");
            }
            $isAllow = strpos($allowType, $ext);

            if ($isAllow == false) {
                throw new ServicesException($ext . '上传文件格式不允许');
            }
            $newName = $this->getRealName($ext, $name);

            if ($images->saveAs($save_path . $newName)) {

                //写入db
                $imageBold = ImagesHelper::fileToBold($save_path . $newName);
                list($width, $height) = getimagesize($save_path . $newName);
                $imageDb = new ComImages();
                $file_md5 = md5_file($save_path . $newName);
                $issetImageDb = ComImages::findOne(['file_md5' => $file_md5]);
                if ($issetImageDb) {
                    $imageDb = $issetImageDb;
                    $imageDb->updated_at = time();
                } else {
                    $imageDb->created_at = $imageDb->updated_at = time();
                }
                $imageDb->width = $width;
                $imageDb->height = $height;
                $imageDb->file_md5 = md5_file($save_path . $newName);
                $imageDb->type = $ext;
                $imageDb->size = $size;
                $imageDb->path = $save . $newName;
                $imageDb->binarydata = $imageBold;
                $imageDb->save();

                return [true,
                    [
                        'originalName' => $images->name,
                        'name' => $newName,
                        'url' => Yii::$app->params['img_url'] . $save . $newName,
                        'size' => $images->size,
                        'type' => $images->type,
                        'state' => 'SUCCESS',
                        'id' => $imageDb->id,
                        'ext' => $ext
                    ]
                ];
            } else {
                throw new ServicesException('上传失败，请更换图片');
            }
        } catch (ServicesException $e) {
            return [false, $e->getMessage()];
        }
    }

    /**
     * 阿里云附件上传
     * @param $fileName
     * @return array
     */
    public function ossAliyun($fileName)
    {
        try {
            $images = UploadedFile::getInstanceByName($fileName);
            list($result, $data) = $this->ossUpload($images);
            return [$result, $data];
        } catch (ServicesException $e) {
            return [false, $e->getMessage()];
        } catch (OssException $e) {
            return [false, $e->getMessage()];
        }

    }

    /**
     * 阿里云附件上传
     * @param $images
     * @return array
     * @throws OssException
     */
    private function ossUpload(UploadedFile $images)
    {
        $allowType = Yii::$app->params['allowUpload'];
        $name = substr($images->name, 0, strrpos($images->name, '.'));

        $ext = $images->getExtension();
        $size = $images->size;

        //文件尺寸限制10M
        if ($size > Yii::$app->params['allow_size']) {
            return [false, '上传文件尺寸超出限制'];
        }
        $isAllow = strpos($allowType, $ext);

        if ($isAllow == false) {
            return [false, '上传文件格式不允许'];
        }
        $newName = $this->getRealName($ext, $name);

        $savePath = 'images/' . date('Ym/d') . "/" . $newName;
        $config = Yii::$app->params['AliyunOss'];
        $ossClient = new OssClient($config['accessKeyId'],
            $config['accessKeySecret'],
            $config['endpoint'],
            $config['isCName'],
            $config['securityToken']
        );
        $ossClient->setTimeout(3600); // 设置Socket层传输数据的超时时间，单位秒，默认5184000秒。
        $ossClient->setConnectTimeout(10); // 设置建立连接的超时时间，单位秒，默认10秒。
        $result = $ossClient->uploadFile($config['bucket'], $savePath, $images->tempName, null);

        if (isset($result['info']['http_code']) && $result['info']['http_code'] == 200) {
            return [
                true, [
                    'originalName' => $images->name,
                    'name' => $newName,
                    'url' => $result['info']['url'],
                    'size' => (string)$images->size,
                    'type' => $images->type,
                    'state' => 'SUCCESS',
                    'ext' => $ext,
                    'savePath' => $savePath
                ]
            ];
        } else {
            return [false, '上传失败，请更换图片'];
        }
    }

    /**
     * 阿里云附件删除
     * @param $images
     * @return array
     * @throws OssException
     */
    public function ossDelete($savePath)
    {
        $config = Yii::$app->params['AliyunOss'];
        $ossClient = new OssClient($config['accessKeyId'],
            $config['accessKeySecret'],
            $config['endpoint'],
            $config['isCName'],
            $config['securityToken']
        );
        $ossClient->setTimeout(3600); // 设置Socket层传输数据的超时时间，单位秒，默认5184000秒。
        $ossClient->setConnectTimeout(10); // 设置建立连接的超时时间，单位秒，默认10秒。
        $result = $ossClient->deleteObject($config['bucket'], $savePath);
        return $result;
    }


    /**
     * 获取新的图片名称
     */
    private function getRealName($ext = "jpg", $name = '')
    {

        if (!empty($name) && isset($name)) {
            return date('YmdHis') . '_' . md5($name) . '.' . $ext;
        } else {
            return date('YmdHis') . '_' . md5(mt_rand(10000, 99999)) . '.' . $ext;
        }

    }
}
